package top.gytf.unifiedcall.producer.response;

import cn.hutool.core.lang.Assert;
import lombok.Builder;
import lombok.Getter;
import lombok.Setter;
import org.springframework.lang.Nullable;
import top.gytf.unifiedcall.common.api.ApiDefinition;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;

/**
 * 通用响应处理上下文
 */
@Builder
public class SimpleResponseHandlerContext implements ResponseHandlerContext {
    @Getter
    private final ApiDefinition apiDefinition;
    @Nullable
    private final Object initialResponse;
    @Setter
    @Getter
    @Nullable
    private Object response;
    @Nullable
    private Object result;
    private boolean completed;
    @Getter
    private final Map<String, Object> parameterMap = new HashMap<>();

    protected SimpleResponseHandlerContext(ApiDefinition apiDefinition, @Nullable Object initialResponse,
            @Nullable Object response, @Nullable Object result, boolean completed) {
        this.apiDefinition = apiDefinition;
        this.initialResponse = response != null && initialResponse == null ? response : initialResponse;
        this.response = response;
        this.result = result;
        this.completed = completed;
    }

    @Override
    public void addParameter(String name, Object value) {
        if (parameterMap.containsKey(name)) {
            throw new IllegalArgumentException("参数[ " + name + " ]已存在");
        }
        setParameter(name, value);
    }

    @Override
    public void setParameter(String name, Object value) {
        parameterMap.put(name, value);
    }

    @Override
    public void removeParameter(String name) {
        parameterMap.remove(name);
    }

    @Override
    public Optional<Object> getParameterOpt(String name) {
        return Optional.ofNullable(parameterMap.get(name));
    }

    @Override
    public <T> Optional<T> getParameterOpt(String name, Class<T> requiredParameterClass) {
        return Optional.ofNullable(getParameter(name))
                .filter(requiredParameterClass::isInstance)
                .map(requiredParameterClass::cast);
    }

    @Override
    public <T> List<T> getParameters(Class<T> requiredParameterClass) {
        return parameterMap.values().stream()
                .filter(requiredParameterClass::isInstance)
                .map(requiredParameterClass::cast)
                .toList();
    }

    @Nullable
    @Override
    public Object getInitialResponse() {
        return this.initialResponse;
    }

    @Nullable
    @Override
    public Object getResult() {
        return this.result;
    }

    @Override
    public void setResult(@Nullable Object result) {
        assertNotCompleted();
        this.result = result;
    }

    @Override
    public boolean isCompleted() {
        return this.completed;
    }

    @Override
    public void complete() {
        assertNotCompleted();
        this.completed = true;
    }

    protected void assertNotCompleted() {
        Assert.isFalse(isCompleted(), "请求处理已被标记完成");
    }
}
